package com.alogic.pipeline.loader;

import com.alogic.load.Loader;
import com.alogic.pipeline.DefaultPipeline;
import com.alogic.pipeline.Pipeline;
import com.anysoft.util.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.w3c.dom.Document;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 从本地文件目录加载
 * @since 1.6.13.35 [20210218 duanyy] <br>
 */
public class FromLocalPath extends Loader.Abstract<Pipeline>{
    /**
     * 文件路径
     */
    protected String home;

    /**
     * 预加载的对象
     */
    protected Map<String,Pipeline> pipelines = new ConcurrentHashMap<String,Pipeline>();

    @Override
    public Pipeline load(String id, boolean cacheAllowed) {
        return pipelines.get(id);
    }

    @Override
    public void configure(Properties p){
        super.configure(p);

        home = PropertiesConstants.getString(p, "path", "");
        if (StringUtils.isNotEmpty(home)){
            LOG.info(String.format("Scan pipeline in %s",home));
            File root = new File(home);
            if (root.exists() && root.isDirectory()){
                scanFileSystem(home,root);
            }
        }
    }

    /**
     * 扫描文件系统
     * @param path
     * @param file
     */
    protected void scanFileSystem(String path, File file) {
        File[] files = file.listFiles();
        for (File item:files){
            if (item.getName().endsWith(".xml")){
                LOG.info(String.format("Found event processor : %s",item.getName()));
                Pipeline p = loadFromFile(item);
                if (p != null && !p.isNull()){
                    pipelines.put(p.getId(), p);
                }
            }
        }
    }

    /**
     * 从指定的文件装入Process
     * @param file Process配置文件
     * @return Process实例
     */
    protected Pipeline loadFromFile(File file){
        InputStream in = null;
        try {
            in = new FileInputStream(file);
            Document doc = XmlTools.loadFromInputStream(in);
            Factory<Pipeline> f = new Factory<Pipeline>();
            Pipeline p =  f.newInstance(
                    doc.getDocumentElement(),Settings.get(),
                    "module", DefaultPipeline.class.getName());
            if (p != null && p.isNull()){
                LOG.warn(String.format("Pipeline id is null ,ignored:%s",
                        XmlTools.node2String(doc.getDocumentElement())));
            }
            return p;
        }catch (Exception ex){
            LOG.error("Can not load file:" + file.getPath());
            LOG.error(ExceptionUtils.getStackTrace(ex));
            return null;
        }finally{
            IOTools.close(in);
        }
    }
}